package com.gitee.feizns.quickstart.web.converter;

import com.gitee.feizns.dynamic.DateUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.lang.NonNull;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Arrays;
import java.util.List;

/**
 * 日期转换器工厂
 * <p>
 *     添加对日期类型{@link TemporalAccessor}
 * </p>
 * @see ConverterFactory
 * @see DateUtils
 * @author feizns
 * @since 2023/2/3
 */
public class ToTemporalAccessorConverterFactory implements ConverterFactory<String, TemporalAccessor> {

    @Override
    public @NonNull <T extends TemporalAccessor> Converter<String, T> getConverter(@NonNull Class<T> targetType) {
        return source -> DateUtils.parse(source, targetType);
    }

    /**
     * Year转换器
     */
    public static final Converter<String, Year> YearConverter = new Converter<String, Year>() {
        @Override
        public Year convert(@NonNull String source) {
            return DateUtils.parse(source, Year.class);
        }
    };

    /**
     * Year转换器
     */
    public static final Converter<String, YearMonth> YearMonthConverter = new Converter<String, YearMonth>() {
        @Override
        public YearMonth convert(@NonNull String source) {
            return DateUtils.parse(source, YearMonth.class);
        }
    };

    /**
     * 当地日期转换器
     */
    public static final Converter<String, LocalDate> LocalDateConverter = new Converter<String, LocalDate>() {
        @Override
        public LocalDate convert(@NonNull String source) {
            return DateUtils.parse(source, LocalDate.class);
        }
    };

    /**
     * 当地时间转换器
     */
    public static final Converter<String, LocalTime> LocalTimeConverter = new Converter<String, LocalTime>() {
        @Override
        public LocalTime convert(@NonNull String source) {
            return DateUtils.parse(source, LocalTime.class);
        }
    };

    /**
     * 当地日期时间转换器
     */
    public static final Converter<String, LocalDateTime> LocalDateTimeConverter = new Converter<String, LocalDateTime>() {
        @Override
        public LocalDateTime convert(@NonNull String source) {
            return DateUtils.parse(source, LocalDateTime.class);
        }
    };

    /**
     * 划日期时间转换器
     */
    public static final Converter<String, ZonedDateTime> ZonedDateTimeConverter = new Converter<String, ZonedDateTime>() {
        @Override
        public ZonedDateTime convert(@NonNull String source) {
            return DateUtils.parse(source, ZonedDateTime.class);
        }
    };

    /**
     * 时区时间转换器
     */
    public static final Converter<String, OffsetTime> OffsetTimeConverter = new Converter<String, OffsetTime>() {
        @Override
        public OffsetTime convert(@NonNull String source) {
            return DateUtils.parse(source, OffsetTime.class);
        }
    };

    /**
     * 时区日期时间转换器
     */
    public static final Converter<String, OffsetDateTime> OffsetDateTimeConverter = new Converter<String, OffsetDateTime>() {
        @Override
        public OffsetDateTime convert(@NonNull String source) {
            return DateUtils.parse(source, OffsetDateTime.class);
        }
    };

    /**
     * 支持java8日期类型的转换器列表
     * @return {@link List}<{@link Converter}<{@link String}, {@link ?} {@link extends} {@link TemporalAccessor}>>
     */
    public static List<Converter<String, ? extends TemporalAccessor>> supportJava8DateTypesConverters() {
        return Arrays.asList(
                YearConverter,
                YearMonthConverter,
                LocalDateConverter,
                LocalTimeConverter,
                LocalDateTimeConverter,
                ZonedDateTimeConverter,
                OffsetTimeConverter,
                OffsetDateTimeConverter
        );
    }

}
